Introduction

Today we are going to go over a bunch of stuff I thought was interesting but didn’t fit specifically into any of the other lessons. This includes some cool ggplot extension packages we haven’t gone over yet, and heatmaps that utilize base R plotting.

A digital cartoon with two illustrations: the top shows the R-logo with a scary face, and a small scared little fuzzy monster holding up a white flag in surrender while under a dark storm cloud. The text above says “at first I was like…” The lower cartoon is a friendly, smiling R-logo jumping up to give a happy fuzzy monster a high-five under a smiling sun and next to colorful flowers. The text above the bottom illustration reads “but now it’s like…”

Artwork by @allison_horst

Load libraries

Loading the libraries that are for each section. Individual libraries are before each section so you can see which go with what plot types.

library(tidyverse) # for everything
## ── Attaching packages ─────────────────────────────────────── tidyverse 1.3.2 ──
## ✔ ggplot2 3.3.6      ✔ purrr   0.3.5 
## ✔ tibble  3.1.8      ✔ dplyr   1.0.10
## ✔ tidyr   1.2.1      ✔ stringr 1.4.1 
## ✔ readr   2.1.3      ✔ forcats 0.5.2 
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()

Really start using an Rproject 📽️

A cartoon of a cracked glass cube looking frustrated with casts on its arm and leg, with bandaids on it, containing “setwd”, looks on at a metal riveted cube labeled “R Proj” holding a skateboard looking sympathetic, and a smaller cube with a helmet on labeled “here” doing a trick on a skateboard.

Artwork by @allison_horst

I have noticed that many of you are still not using RProjects. I would really recommend that for easy file management that you do. Here is an a chapter in R for Data Science on how to set one up. If you want to start using Git in the future, you will need to set up a project.

gghighlight 🔦

A cartoon of 3 fuzzy monsters making a ggplot. Titled gghighlight: highlight geoms in ggplot, and shows an example of a line plot with many grey lines in the background, and a purple and blue line highlighted in color allowing the viewer to see the series that have a max temp value over 20.

Artwork by @allison_horst

The package gghighlight allows you to highlight certain geoms in ggplot. Doing this helps your reader focus on the thing you want them to, and helps prevent plot spaghetti. To practice with gghighlight we are going to use some data from the R package gapminder

Install

installl.packages("gghighlight")
install.packages("gapminder")

Load libraries

First let’s load our libraries.

library(gghighlight) # for highlighting
library(gapminder) # where data is

Wrangle

We can create a dataframe that includes only the data for the countries in the continent Americas.

gapminder_americas <- gapminder %>%
  filter(continent == "Americas")

Plot

If we look at all the countries at once, we get plot spaghetti 🍝.

gapminder_americas %>%
  ggplot(aes(x = year, y = lifeExp, group = country, color = country)) +
  geom_line() +
  theme_minimal() +
  labs(x = "Year",
       y = "Life Expectancy (years)",
       title = "Life Expectancy in Countries in the Americas",
       subtitle = "From 1952 to 2007",
       caption = "Data from gapminder.org")

Create a lineplot showing the life expectacy over 1952 to 2007 for all countries, highlighting the United States.

# highlight just the US
gapminder_americas %>%
  ggplot(aes(x = year, y = lifeExp, group = country, color = country)) +
  geom_line() +
  gghighlight(country == "United States") +
  theme_minimal() +
  labs(x = "Year",
       y = "Life Expectancy (years)",
       title = "Life Expectancy in Countries in the Americas",
       subtitle = "From 1952 to 2007",
       caption = "Data from gapminder.org")

Facet our plot, and highlight the country for each facet.

# facet and highlight each country
gapminder_americas %>%
  ggplot(aes(x = year, y = lifeExp)) +
  geom_line(aes(color = country)) +
  gghighlight() +
  theme_minimal() +
  theme(legend.position = "none",
        strip.text.x = element_text(size = 8),
        axis.text.x = element_text(angle = 90)) +
  facet_wrap(~country) +
  labs(x = "Year",
       y = "Life Expectancy (years)",
       title = "Life Expectancy in Countries in the Americas",
       subtitle = "From 1952 to 2007",
       caption = "Data from gapminder.org")

patchwork, a little more 📈📊📉

Fuzzy cartoon monsters in white gloves and uniforms hanging multiple plots together on a wall, with an artist monster wearing a beret and smock directing them to the correct orientation. There is a blueprint plan on the wall showing how the plots should be arranged. Stylized title font reads “patchwork - combine & arrange your ggplots!”

Artwork by @allison_horst

We have talked a bit about patchwork in the lecture on PCA but its such a useful package I wanted to go over it a bit more. The goal of patchwork is to make it very simple to combine plots together.

Load libraries

library(patchwork)
library(palmerpenguins) # for making some plots to assemble

Make some plots

plot1 <- penguins %>%
  ggplot(aes(x = species, y = body_mass_g, color = species)) +
  geom_boxplot()

plot2 <- penguins %>%
  ggplot(aes(x = bill_length_mm, y = bill_depth_mm, color = species)) +
  geom_point()

plot3 <- penguins %>%
  drop_na() %>%
  ggplot(aes(x = island, y = flipper_length_mm, color = species)) +
  geom_boxplot() +
  facet_wrap(vars(sex))

Combine plots

(plot1 + plot2) / plot3 
## Warning: Removed 2 rows containing non-finite values (stat_boxplot).
## Warning: Removed 2 rows containing missing values (geom_point).

(plot1 + plot2) / plot3 + plot_annotation(tag_levels = "A",
                                          title = "Here is some information about penguins")
## Warning: Removed 2 rows containing non-finite values (stat_boxplot).
## Warning: Removed 2 rows containing missing values (geom_point).

gganimate 💃

Cartoon of a bunch of monsters watching data points of varing color and shape fly across a screen like fireworks. Several monsters are lighting the data off like fireworks. Stylized text reads “gganimate: action figures!”

Artwork by @allison_horst

https://gganimate.com/reference/transition_states.html

Install

install.packages("gganimate") # gganimate
install.packages("gapminder") # gapminder data for example
install.packages("magick") # for gif rendering

Load libraries

library(gganimate)
library(ggrepel) # for text/label repelling
library(magick) # for gif rendering
## Linking to ImageMagick 6.9.12.3
## Enabled features: cairo, fontconfig, freetype, heic, lcms, pango, raw, rsvg, webp
## Disabled features: fftw, ghostscript, x11

Plot

plot_to_animate <- gapminder_americas %>%
  ggplot(aes(x = lifeExp, y = pop, fill = country, label = country)) +
  geom_point(shape = 21, color = "black") +
  geom_text_repel() +
  scale_y_log10() +
  theme_classic() +
  theme(legend.position = 'none') +
  labs(title = "Population and Life Expectancy in the Americas",
       subtitle = 'Year: {closest_state}', 
       x = "Life Expectancy", 
       y = "Log10 Population") +
  transition_states(year) # what to gif over

# set parameters for your animation
animated_plot <- animate(plot = plot_to_animate, 
                        duration = 10, 
                        fps = 10, 
                        width = 700, 
                        height = 700,
                        renderer = magick_renderer())

Print

Print your animation.

animated_plot

Save

Save your animation.

# save it
anim_save(filename = "gapminder_gif.gif",
          animation = last_animation())

ggradar 📡

The package ggradar allows you to create radar plots, which allow the plotting of multidimensional data on a two dimension chart. Typically with these plots, the goal is to compare the variables on the plot across different groups. We are going to try this out with the coffee tasting data from the distributions recitation

Install ggradar if you don’t already have it. This package is not available on CRAN for the newest version of R, so we can use devtools and install_github() to install it. You could also try using install.packages() and see if that works for you.

devtools::install_github("ricardo-bion/ggradar",
                         dependencies = TRUE)
library(ggradar)
library(scales) # for scaling data

# load coffee data from distributions recitation
tuesdata <- tidytuesdayR::tt_load('2020-07-07')
## 
##  Downloading file 1 of 1: `coffee_ratings.csv`
# extract out df on coffee_ratings
coffee <- tuesdata$coffee_ratings

# what are the column names again?
colnames(coffee)
##  [1] "total_cup_points"      "species"               "owner"                
##  [4] "country_of_origin"     "farm_name"             "lot_number"           
##  [7] "mill"                  "ico_number"            "company"              
## [10] "altitude"              "region"                "producer"             
## [13] "number_of_bags"        "bag_weight"            "in_country_partner"   
## [16] "harvest_year"          "grading_date"          "owner_1"              
## [19] "variety"               "processing_method"     "aroma"                
## [22] "flavor"                "aftertaste"            "acidity"              
## [25] "body"                  "balance"               "uniformity"           
## [28] "clean_cup"             "sweetness"             "cupper_points"        
## [31] "moisture"              "category_one_defects"  "quakers"              
## [34] "color"                 "category_two_defects"  "expiration"           
## [37] "certification_body"    "certification_address" "certification_contact"
## [40] "unit_of_measurement"   "altitude_low_meters"   "altitude_high_meters" 
## [43] "altitude_mean_meters"
coffee_radar <- coffee %>%
  select(species, aroma:cupper_points) %>% # first column is the groups
  mutate_at(vars(-species), rescale) %>% # columns need to be between 0 and 1
  group_by(species) %>%
  summarize_if(is.numeric, mean) 

coffee_labels <- c("Aroma",
                   "Flavor",
                   "Aftertaste",
                   "Acidity",
                   "Body",
                   "Balance",
                   "Uniformity",
                   "Clean cup",
                   "Sweetness",
                   "Cupper points")
ggradar(coffee_radar)

ggradar(coffee_radar,
        axis.labels = coffee_labels,
        legend.position = "bottom",
        axis.label.size = 3,
        grid.label.size = 5) +
  theme(legend.key = element_rect(fill = NA, color = NA),
        plot.title = element_text(size = 16),
        legend.text = element_text(size = 12)) +
  labs(title = "Difference in average coffee cupper score \nin Arabica and Robusta beans")

Heatmaps 🟥⬜️🟦

Install

install.packages("pheatmap")

Load libraries

library(pheatmap)

Plot

pheatmap(mtcars)

pheatmap(mtcars, 
         scale = "column",
         cluster_rows = TRUE) # cluster rows based on similarity

ConplexHeatmap

The package ComplexHeatmap allows more customized and complicated heatmaps to be produced. If you are interested in making heatmaps, this package is worth to check out.

In class

In class, we will practice making use of these leftovers.

LS0tCnRpdGxlOiAiTGVmdG92ZXIgdGlkYml0cyIKYXV0aG9yOiAiSmVzc2ljYSBDb29wZXJzdG9uZSIKZGF0ZTogIjExLzE1LzIwMjIiCm91dHB1dDoKICBodG1sX2RvY3VtZW50OgogICAgdG9jOiB0cnVlCiAgICB0b2NfZGVwdGg6IDUKICAgIHRvY19mbG9hdDogdHJ1ZQogICAgdGhlbWU6IGZsYXRseQogICAgY29kZV9kb3dubG9hZDogdHJ1ZQotLS0KCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUpCmBgYAoKIyMgSW50cm9kdWN0aW9uCgpUb2RheSB3ZSBhcmUgZ29pbmcgdG8gZ28gb3ZlciBhIGJ1bmNoIG9mIHN0dWZmIEkgdGhvdWdodCB3YXMgaW50ZXJlc3RpbmcgYnV0IGRpZG4ndCBmaXQgc3BlY2lmaWNhbGx5IGludG8gYW55IG9mIHRoZSBvdGhlciBsZXNzb25zLiBUaGlzIGluY2x1ZGVzIHNvbWUgY29vbCBnZ3Bsb3QgZXh0ZW5zaW9uIHBhY2thZ2VzIHdlIGhhdmVuJ3QgZ29uZSBvdmVyIHlldCwgYW5kIGhlYXRtYXBzIHRoYXQgdXRpbGl6ZSBiYXNlIFIgcGxvdHRpbmcuCgpgYGB7ciB3YXMgc2FkIG5vdyBoYXBweSwgZmlnLmFsdCA9ICJBIGRpZ2l0YWwgY2FydG9vbiB3aXRoIHR3byBpbGx1c3RyYXRpb25zOiB0aGUgdG9wIHNob3dzIHRoZSBSLWxvZ28gd2l0aCBhIHNjYXJ5IGZhY2UsIGFuZCBhIHNtYWxsIHNjYXJlZCBsaXR0bGUgZnV6enkgbW9uc3RlciBob2xkaW5nIHVwIGEgd2hpdGUgZmxhZyBpbiBzdXJyZW5kZXIgd2hpbGUgdW5kZXIgYSBkYXJrIHN0b3JtIGNsb3VkLiBUaGUgdGV4dCBhYm92ZSBzYXlzIOKAnGF0IGZpcnN0IEkgd2FzIGxpa2XigKbigJ0gVGhlIGxvd2VyIGNhcnRvb24gaXMgYSBmcmllbmRseSwgc21pbGluZyBSLWxvZ28ganVtcGluZyB1cCB0byBnaXZlIGEgaGFwcHkgZnV6enkgbW9uc3RlciBhIGhpZ2gtZml2ZSB1bmRlciBhIHNtaWxpbmcgc3VuIGFuZCBuZXh0IHRvIGNvbG9yZnVsIGZsb3dlcnMuIFRoZSB0ZXh0IGFib3ZlIHRoZSBib3R0b20gaWxsdXN0cmF0aW9uIHJlYWRzIOKAnGJ1dCBub3cgaXTigJlzIGxpa2XigKbigJ0iLCBmaWcuY2FwPSAiQXJ0d29yayBieSBbQGFsbGlzb25faG9yc3RdKGh0dHBzOi8vdHdpdHRlci5jb20vYWxsaXNvbl9ob3JzdCkiLCBvdXQud2lkdGggPSAiNzAlIiwgZmlnLmFsaWduID0gImNlbnRlciIsIGVjaG8gPSBGQUxTRX0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoImltZy9zYWQtbm93LWhhcHB5LnBuZyIpCmBgYAoKIyMjIExvYWQgbGlicmFyaWVzCkxvYWRpbmcgdGhlIGxpYnJhcmllcyB0aGF0IGFyZSBmb3IgZWFjaCBzZWN0aW9uLiBJbmRpdmlkdWFsIGxpYnJhcmllcyBhcmUgYmVmb3JlIGVhY2ggc2VjdGlvbiBzbyB5b3UgY2FuIHNlZSB3aGljaCBnbyB3aXRoIHdoYXQgcGxvdCB0eXBlcy4KYGBge3IgbG9hZCBsaWJyYXJpZXN9CmxpYnJhcnkodGlkeXZlcnNlKSAjIGZvciBldmVyeXRoaW5nCmBgYAoKIyMgUmVhbGx5IHN0YXJ0IHVzaW5nIGFuIFJwcm9qZWN0IPCfk73vuI8KCmBgYHtyIHJwcm9qIGlsbHVzdHJhdGlvbiwgZmlnLmFsdCA9ICJBIGNhcnRvb24gb2YgYSBjcmFja2VkIGdsYXNzIGN1YmUgbG9va2luZyBmcnVzdHJhdGVkIHdpdGggY2FzdHMgb24gaXRzIGFybSBhbmQgbGVnLCB3aXRoIGJhbmRhaWRzIG9uIGl0LCBjb250YWluaW5nIOKAnHNldHdk4oCdLCBsb29rcyBvbiBhdCBhIG1ldGFsIHJpdmV0ZWQgY3ViZSBsYWJlbGVkIOKAnFIgUHJvauKAnSBob2xkaW5nIGEgc2thdGVib2FyZCBsb29raW5nIHN5bXBhdGhldGljLCBhbmQgYSBzbWFsbGVyIGN1YmUgd2l0aCBhIGhlbG1ldCBvbiBsYWJlbGVkIOKAnGhlcmXigJ0gZG9pbmcgYSB0cmljayBvbiBhIHNrYXRlYm9hcmQuIiwgZmlnLmNhcD0gIkFydHdvcmsgYnkgW0BhbGxpc29uX2hvcnN0XShodHRwczovL3R3aXR0ZXIuY29tL2FsbGlzb25faG9yc3QpIiwgb3V0LndpZHRoID0gIjcwJSIsIGZpZy5hbGlnbiA9ICJjZW50ZXIiLCBlY2hvID0gRkFMU0V9CmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKCJpbWcvcnByb2oucG5nIikKYGBgCgpJIGhhdmUgbm90aWNlZCB0aGF0IG1hbnkgb2YgeW91IGFyZSBzdGlsbCBub3QgdXNpbmcgUlByb2plY3RzLiBJIHdvdWxkIHJlYWxseSByZWNvbW1lbmQgdGhhdCBmb3IgZWFzeSBmaWxlIG1hbmFnZW1lbnQgdGhhdCB5b3UgZG8uIEhlcmUgaXMgYW4gW2EgY2hhcHRlciBpbiBSIGZvciBEYXRhIFNjaWVuY2VdKGh0dHBzOi8vcjRkcy5oYWQuY28ubnovd29ya2Zsb3ctcHJvamVjdHMuaHRtbCkgb24gaG93IHRvIHNldCBvbmUgdXAuIElmIHlvdSB3YW50IHRvIHN0YXJ0IHVzaW5nIEdpdCBpbiB0aGUgZnV0dXJlLCB5b3Ugd2lsbCBuZWVkIHRvIHNldCB1cCBhIHByb2plY3QuCgojIyBnZ2hpZ2hsaWdodCDwn5SmCgpgYGB7ciBnZ2hpZ2hsaWdodCBpbGx1c3RyYXRpb24sIGZpZy5hbHQgPSAiQSBjYXJ0b29uIG9mIDMgZnV6enkgbW9uc3RlcnMgbWFraW5nIGEgZ2dwbG90LiBUaXRsZWQgZ2doaWdobGlnaHQ6IGhpZ2hsaWdodCBnZW9tcyBpbiBnZ3Bsb3QsIGFuZCBzaG93cyBhbiBleGFtcGxlIG9mIGEgbGluZSBwbG90IHdpdGggbWFueSBncmV5IGxpbmVzIGluIHRoZSBiYWNrZ3JvdW5kLCBhbmQgYSBwdXJwbGUgYW5kIGJsdWUgbGluZSBoaWdobGlnaHRlZCBpbiBjb2xvciBhbGxvd2luZyB0aGUgdmlld2VyIHRvIHNlZSB0aGUgc2VyaWVzIHRoYXQgaGF2ZSBhIG1heCB0ZW1wIHZhbHVlIG92ZXIgMjAuIiwgZmlnLmNhcD0gIkFydHdvcmsgYnkgW0BhbGxpc29uX2hvcnN0XShodHRwczovL3R3aXR0ZXIuY29tL2FsbGlzb25faG9yc3QpIiwgb3V0LndpZHRoID0gIjcwJSIsIGZpZy5hbGlnbiA9ICJjZW50ZXIiLCBlY2hvID0gRkFMU0V9CmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKCJpbWcvZ2doaWdobGlnaHQuanBlZyIpCmBgYAoKVGhlIHBhY2thZ2UgW2BnZ2hpZ2hsaWdodGBdKGh0dHBzOi8veXV0YW5uaWhpbGF0aW9uLmdpdGh1Yi5pby9nZ2hpZ2hsaWdodC9pbmRleC5odG1sKSBhbGxvd3MgeW91IHRvIGhpZ2hsaWdodCBjZXJ0YWluIGdlb21zIGluIGdncGxvdC4gRG9pbmcgdGhpcyBoZWxwcyB5b3VyIHJlYWRlciBmb2N1cyBvbiB0aGUgdGhpbmcgeW91IHdhbnQgdGhlbSB0bywgYW5kIGhlbHBzIHByZXZlbnQgcGxvdCBzcGFnaGV0dGkuIFRvIHByYWN0aWNlIHdpdGggYGdnaGlnaGxpZ2h0YCB3ZSBhcmUgZ29pbmcgdG8gdXNlIHNvbWUgZGF0YSBmcm9tIHRoZSBSIHBhY2thZ2UgW2BnYXBtaW5kZXJgXShodHRwczovL3d3dy5yZG9jdW1lbnRhdGlvbi5vcmcvcGFja2FnZXMvZ2FwbWluZGVyL3ZlcnNpb25zLzAuMy4wKQoKIyMjIEluc3RhbGwKYGBge3IgZ2doaWdobGlnaHQgaW5zdGFsbCwgZXZhbCA9IEZBTFNFfQppbnN0YWxsbC5wYWNrYWdlcygiZ2doaWdobGlnaHQiKQppbnN0YWxsLnBhY2thZ2VzKCJnYXBtaW5kZXIiKQpgYGAKCiMjIyBMb2FkIGxpYnJhcmllcwpGaXJzdCBsZXQncyBsb2FkIG91ciBsaWJyYXJpZXMuCmBgYHtyIGdnaGxpZ2hsaWdodCBsaWJyYXJpZXN9CmxpYnJhcnkoZ2doaWdobGlnaHQpICMgZm9yIGhpZ2hsaWdodGluZwpsaWJyYXJ5KGdhcG1pbmRlcikgIyB3aGVyZSBkYXRhIGlzCmBgYAoKIyMjIFdyYW5nbGUKV2UgY2FuIGNyZWF0ZSBhIGRhdGFmcmFtZSB0aGF0IGluY2x1ZGVzIG9ubHkgdGhlIGRhdGEgZm9yIHRoZSBjb3VudHJpZXMgaW4gdGhlIGNvbnRpbmVudCBBbWVyaWNhcy4KYGBge3IgZ2dobGlnaGxpZ2h0IHdyYW5nbGluZ30KZ2FwbWluZGVyX2FtZXJpY2FzIDwtIGdhcG1pbmRlciAlPiUKICBmaWx0ZXIoY29udGluZW50ID09ICJBbWVyaWNhcyIpCmBgYAoKIyMjIFBsb3QKSWYgd2UgbG9vayBhdCBhbGwgdGhlIGNvdW50cmllcyBhdCBvbmNlLCB3ZSBnZXQgcGxvdCBzcGFnaGV0dGkg8J+NnS4KYGBge3IgZ2doaWdobGlnaHQgYmFzZSBwbG90LCB3YXJuaW5nID0gRkFMU0UsIG1lc3NhZ2UgPSBGQUxTRX0KZ2FwbWluZGVyX2FtZXJpY2FzICU+JQogIGdncGxvdChhZXMoeCA9IHllYXIsIHkgPSBsaWZlRXhwLCBncm91cCA9IGNvdW50cnksIGNvbG9yID0gY291bnRyeSkpICsKICBnZW9tX2xpbmUoKSArCiAgdGhlbWVfbWluaW1hbCgpICsKICBsYWJzKHggPSAiWWVhciIsCiAgICAgICB5ID0gIkxpZmUgRXhwZWN0YW5jeSAoeWVhcnMpIiwKICAgICAgIHRpdGxlID0gIkxpZmUgRXhwZWN0YW5jeSBpbiBDb3VudHJpZXMgaW4gdGhlIEFtZXJpY2FzIiwKICAgICAgIHN1YnRpdGxlID0gIkZyb20gMTk1MiB0byAyMDA3IiwKICAgICAgIGNhcHRpb24gPSAiRGF0YSBmcm9tIGdhcG1pbmRlci5vcmciKQpgYGAKCkNyZWF0ZSBhIGxpbmVwbG90IHNob3dpbmcgdGhlIGxpZmUgZXhwZWN0YWN5IG92ZXIgMTk1MiB0byAyMDA3IGZvciBhbGwgY291bnRyaWVzLCBoaWdobGlnaHRpbmcgdGhlIFVuaXRlZCBTdGF0ZXMuCmBgYHtyIGdnaGlnaGxpZ2h0IFVTLCB3YXJuaW5nID0gRkFMU0UsIG1lc3NhZ2UgPSBGQUxTRX0KIyBoaWdobGlnaHQganVzdCB0aGUgVVMKZ2FwbWluZGVyX2FtZXJpY2FzICU+JQogIGdncGxvdChhZXMoeCA9IHllYXIsIHkgPSBsaWZlRXhwLCBncm91cCA9IGNvdW50cnksIGNvbG9yID0gY291bnRyeSkpICsKICBnZW9tX2xpbmUoKSArCiAgZ2doaWdobGlnaHQoY291bnRyeSA9PSAiVW5pdGVkIFN0YXRlcyIpICsKICB0aGVtZV9taW5pbWFsKCkgKwogIGxhYnMoeCA9ICJZZWFyIiwKICAgICAgIHkgPSAiTGlmZSBFeHBlY3RhbmN5ICh5ZWFycykiLAogICAgICAgdGl0bGUgPSAiTGlmZSBFeHBlY3RhbmN5IGluIENvdW50cmllcyBpbiB0aGUgQW1lcmljYXMiLAogICAgICAgc3VidGl0bGUgPSAiRnJvbSAxOTUyIHRvIDIwMDciLAogICAgICAgY2FwdGlvbiA9ICJEYXRhIGZyb20gZ2FwbWluZGVyLm9yZyIpCmBgYAoKRmFjZXQgb3VyIHBsb3QsIGFuZCBoaWdobGlnaHQgdGhlIGNvdW50cnkgZm9yIGVhY2ggZmFjZXQuCmBgYHtyIGdnaGlnaGxpZ2h0IGZhY2V0LCB3YXJuaW5nID0gRkFMU0UsIG1lc3NhZ2UgPSBGQUxTRX0KIyBmYWNldCBhbmQgaGlnaGxpZ2h0IGVhY2ggY291bnRyeQpnYXBtaW5kZXJfYW1lcmljYXMgJT4lCiAgZ2dwbG90KGFlcyh4ID0geWVhciwgeSA9IGxpZmVFeHApKSArCiAgZ2VvbV9saW5lKGFlcyhjb2xvciA9IGNvdW50cnkpKSArCiAgZ2doaWdobGlnaHQoKSArCiAgdGhlbWVfbWluaW1hbCgpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsCiAgICAgICAgc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4KSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwKSkgKwogIGZhY2V0X3dyYXAofmNvdW50cnkpICsKICBsYWJzKHggPSAiWWVhciIsCiAgICAgICB5ID0gIkxpZmUgRXhwZWN0YW5jeSAoeWVhcnMpIiwKICAgICAgIHRpdGxlID0gIkxpZmUgRXhwZWN0YW5jeSBpbiBDb3VudHJpZXMgaW4gdGhlIEFtZXJpY2FzIiwKICAgICAgIHN1YnRpdGxlID0gIkZyb20gMTk1MiB0byAyMDA3IiwKICAgICAgIGNhcHRpb24gPSAiRGF0YSBmcm9tIGdhcG1pbmRlci5vcmciKQpgYGAKCiMjIHBhdGNod29yaywgYSBsaXR0bGUgbW9yZSDwn5OI8J+TivCfk4kKCmBgYHtyIHBhdGNod29yayBpbGx1c3RyYXRpb24sIGZpZy5hbHQgPSAiRnV6enkgY2FydG9vbiBtb25zdGVycyBpbiB3aGl0ZSBnbG92ZXMgYW5kIHVuaWZvcm1zIGhhbmdpbmcgbXVsdGlwbGUgcGxvdHMgdG9nZXRoZXIgb24gYSB3YWxsLCB3aXRoIGFuIGFydGlzdCBtb25zdGVyIHdlYXJpbmcgYSBiZXJldCBhbmQgc21vY2sgZGlyZWN0aW5nIHRoZW0gdG8gdGhlIGNvcnJlY3Qgb3JpZW50YXRpb24uIFRoZXJlIGlzIGEgYmx1ZXByaW50IHBsYW4gb24gdGhlIHdhbGwgc2hvd2luZyBob3cgdGhlIHBsb3RzIHNob3VsZCBiZSBhcnJhbmdlZC4gU3R5bGl6ZWQgdGl0bGUgZm9udCByZWFkcyDigJxwYXRjaHdvcmsgLSBjb21iaW5lICYgYXJyYW5nZSB5b3VyIGdncGxvdHMh4oCdIiwgZmlnLmNhcD0gIkFydHdvcmsgYnkgW0BhbGxpc29uX2hvcnN0XShodHRwczovL3R3aXR0ZXIuY29tL2FsbGlzb25faG9yc3QpIiwgb3V0LndpZHRoID0gIjcwJSIsIGZpZy5hbGlnbiA9ICJjZW50ZXIiLCBlY2hvID0gRkFMU0V9CmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKCJpbWcvcGF0Y2h3b3JrLnBuZyIpCmBgYAoKV2UgaGF2ZSB0YWxrZWQgYSBiaXQgYWJvdXQgW2BwYXRjaHdvcmtgXShodHRwczovL3BhdGNod29yay5kYXRhLWltYWdpbmlzdC5jb20vKSBpbiB0aGUgW2xlY3R1cmUgb24gUENBXShodHRwczovL2RhdGF2aXN1YWxpemluZy5uZXRsaWZ5LmFwcC80XzA5X3BjYS8wOV9wY2EjcGF0Y2h3b3JrKSBidXQgaXRzIHN1Y2ggYSB1c2VmdWwgcGFja2FnZSBJIHdhbnRlZCB0byBnbyBvdmVyIGl0IGEgYml0IG1vcmUuIFRoZSBnb2FsIG9mIGBwYXRjaHdvcmtgIGlzIHRvIG1ha2UgaXQgdmVyeSBzaW1wbGUgdG8gY29tYmluZSBwbG90cyB0b2dldGhlci4KCiMjIyBMb2FkIGxpYnJhcmllcwpgYGB7ciBwYXRjaHdvcmsgbGlicmFyeX0KbGlicmFyeShwYXRjaHdvcmspCmxpYnJhcnkocGFsbWVycGVuZ3VpbnMpICMgZm9yIG1ha2luZyBzb21lIHBsb3RzIHRvIGFzc2VtYmxlCmBgYAoKIyMjIE1ha2Ugc29tZSBwbG90cwoKYGBge3IgcGF0Y2h3b3JrIG1ha2UgcGxvdHN9CnBsb3QxIDwtIHBlbmd1aW5zICU+JQogIGdncGxvdChhZXMoeCA9IHNwZWNpZXMsIHkgPSBib2R5X21hc3NfZywgY29sb3IgPSBzcGVjaWVzKSkgKwogIGdlb21fYm94cGxvdCgpCgpwbG90MiA8LSBwZW5ndWlucyAlPiUKICBnZ3Bsb3QoYWVzKHggPSBiaWxsX2xlbmd0aF9tbSwgeSA9IGJpbGxfZGVwdGhfbW0sIGNvbG9yID0gc3BlY2llcykpICsKICBnZW9tX3BvaW50KCkKCnBsb3QzIDwtIHBlbmd1aW5zICU+JQogIGRyb3BfbmEoKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSBpc2xhbmQsIHkgPSBmbGlwcGVyX2xlbmd0aF9tbSwgY29sb3IgPSBzcGVjaWVzKSkgKwogIGdlb21fYm94cGxvdCgpICsKICBmYWNldF93cmFwKHZhcnMoc2V4KSkKYGBgCgojIyMgQ29tYmluZSBwbG90cwoKYGBge3IgcGF0Y2h3b3JrIHJlZ3VsYXIgY29tYmluZX0KKHBsb3QxICsgcGxvdDIpIC8gcGxvdDMgCmBgYAoKYGBge3IgcGF0Y2h3b3JrIGFkZCBwYW5lbCBsYWJlbHMgYW5kIHRpdGxlfQoocGxvdDEgKyBwbG90MikgLyBwbG90MyArIHBsb3RfYW5ub3RhdGlvbih0YWdfbGV2ZWxzID0gIkEiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aXRsZSA9ICJIZXJlIGlzIHNvbWUgaW5mb3JtYXRpb24gYWJvdXQgcGVuZ3VpbnMiKQpgYGAKCiMjIGdnYW5pbWF0ZSDwn5KDCgpgYGB7ciBnZ2FuaW1hdGUgaWxsdXN0cmF0aW9uLCBmaWcuYWx0ID0gIkNhcnRvb24gb2YgYSBidW5jaCBvZiBtb25zdGVycyB3YXRjaGluZyBkYXRhIHBvaW50cyBvZiB2YXJpbmcgY29sb3IgYW5kIHNoYXBlIGZseSBhY3Jvc3MgYSBzY3JlZW4gbGlrZSBmaXJld29ya3MuIFNldmVyYWwgbW9uc3RlcnMgYXJlIGxpZ2h0aW5nIHRoZSBkYXRhIG9mZiBsaWtlIGZpcmV3b3Jrcy4gU3R5bGl6ZWQgdGV4dCByZWFkcyDigJxnZ2FuaW1hdGU6IGFjdGlvbiBmaWd1cmVzIeKAnSIsIGZpZy5jYXA9ICJBcnR3b3JrIGJ5IFtAYWxsaXNvbl9ob3JzdF0oaHR0cHM6Ly90d2l0dGVyLmNvbS9hbGxpc29uX2hvcnN0KSIsIG91dC53aWR0aCA9ICI3MCUiLCBmaWcuYWxpZ24gPSAiY2VudGVyIiwgZWNobyA9IEZBTFNFfQprbml0cjo6aW5jbHVkZV9ncmFwaGljcygiaW1nL2dnYW5pbWF0ZS5wbmciKQpgYGAKCmh0dHBzOi8vZ2dhbmltYXRlLmNvbS9yZWZlcmVuY2UvdHJhbnNpdGlvbl9zdGF0ZXMuaHRtbAoKIyMjIEluc3RhbGwKYGBge3IgZ2dhbmltYXRlIGluc3RhbGwsIGV2YWwgPSBGQUxTRX0KaW5zdGFsbC5wYWNrYWdlcygiZ2dhbmltYXRlIikgIyBnZ2FuaW1hdGUKaW5zdGFsbC5wYWNrYWdlcygiZ2FwbWluZGVyIikgIyBnYXBtaW5kZXIgZGF0YSBmb3IgZXhhbXBsZQppbnN0YWxsLnBhY2thZ2VzKCJtYWdpY2siKSAjIGZvciBnaWYgcmVuZGVyaW5nCmBgYAoKIyMjIExvYWQgbGlicmFyaWVzCmBgYHtyIGdnYW5pbWF0ZSBsaWJyYXJpZXN9CmxpYnJhcnkoZ2dhbmltYXRlKQpsaWJyYXJ5KGdncmVwZWwpICMgZm9yIHRleHQvbGFiZWwgcmVwZWxsaW5nCmxpYnJhcnkobWFnaWNrKSAjIGZvciBnaWYgcmVuZGVyaW5nCmBgYAoKIyMjIFBsb3QKYGBge3IgZ2dhbmltYXRlIG1ha2UgcGxvdCBhbmQgc2V0IHBhcmFtc30KcGxvdF90b19hbmltYXRlIDwtIGdhcG1pbmRlcl9hbWVyaWNhcyAlPiUKICBnZ3Bsb3QoYWVzKHggPSBsaWZlRXhwLCB5ID0gcG9wLCBmaWxsID0gY291bnRyeSwgbGFiZWwgPSBjb3VudHJ5KSkgKwogIGdlb21fcG9pbnQoc2hhcGUgPSAyMSwgY29sb3IgPSAiYmxhY2siKSArCiAgZ2VvbV90ZXh0X3JlcGVsKCkgKwogIHNjYWxlX3lfbG9nMTAoKSArCiAgdGhlbWVfY2xhc3NpYygpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAnbm9uZScpICsKICBsYWJzKHRpdGxlID0gIlBvcHVsYXRpb24gYW5kIExpZmUgRXhwZWN0YW5jeSBpbiB0aGUgQW1lcmljYXMiLAogICAgICAgc3VidGl0bGUgPSAnWWVhcjoge2Nsb3Nlc3Rfc3RhdGV9JywgCiAgICAgICB4ID0gIkxpZmUgRXhwZWN0YW5jeSIsIAogICAgICAgeSA9ICJMb2cxMCBQb3B1bGF0aW9uIikgKwogIHRyYW5zaXRpb25fc3RhdGVzKHllYXIpICMgd2hhdCB0byBnaWYgb3ZlcgoKIyBzZXQgcGFyYW1ldGVycyBmb3IgeW91ciBhbmltYXRpb24KYW5pbWF0ZWRfcGxvdCA8LSBhbmltYXRlKHBsb3QgPSBwbG90X3RvX2FuaW1hdGUsIAogICAgICAgICAgICAgICAgICAgICAgICBkdXJhdGlvbiA9IDEwLCAKICAgICAgICAgICAgICAgICAgICAgICAgZnBzID0gMTAsIAogICAgICAgICAgICAgICAgICAgICAgICB3aWR0aCA9IDcwMCwgCiAgICAgICAgICAgICAgICAgICAgICAgIGhlaWdodCA9IDcwMCwKICAgICAgICAgICAgICAgICAgICAgICAgcmVuZGVyZXIgPSBtYWdpY2tfcmVuZGVyZXIoKSkKYGBgCgojIyMgUHJpbnQKUHJpbnQgeW91ciBhbmltYXRpb24uCmBgYHtyIGdnYW5pbWF0ZSBzaG93IGFuaW1hdGlvbiwgZXZhbCA9IEZBTFNFfQphbmltYXRlZF9wbG90CmBgYAoKYGBge3IgZ2dhbmltYXRlIGFjdHVhbGx5IHNob3cgYW5pbWF0aW9uLCBlY2hvID0gRkFMU0V9CmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKCJnYXBtaW5kZXJfZ2lmLmdpZiIpCmBgYAoKCiMjIyBTYXZlClNhdmUgeW91ciBhbmltYXRpb24uCmBgYHtyIGdnYW5pbWF0ZSBzYXZlIGFuaW1hdGlvbiwgZXZhbCA9IEZBTFNFfQojIHNhdmUgaXQKYW5pbV9zYXZlKGZpbGVuYW1lID0gImdhcG1pbmRlcl9naWYuZ2lmIiwKICAgICAgICAgIGFuaW1hdGlvbiA9IGxhc3RfYW5pbWF0aW9uKCkpCmBgYAoKIyMgZ2dyYWRhciDwn5OhClRoZSBwYWNrYWdlIFtgZ2dyYWRhcmBdKGh0dHBzOi8vZ2l0aHViLmNvbS9yaWNhcmRvLWJpb24vZ2dyYWRhcikgYWxsb3dzIHlvdSB0byBjcmVhdGUgcmFkYXIgcGxvdHMsIHdoaWNoIGFsbG93IHRoZSBwbG90dGluZyBvZiBtdWx0aWRpbWVuc2lvbmFsIGRhdGEgb24gYSB0d28gZGltZW5zaW9uIGNoYXJ0LiBUeXBpY2FsbHkgd2l0aCB0aGVzZSBwbG90cywgdGhlIGdvYWwgaXMgdG8gY29tcGFyZSB0aGUgdmFyaWFibGVzIG9uIHRoZSBwbG90IGFjcm9zcyBkaWZmZXJlbnQgZ3JvdXBzLiBXZSBhcmUgZ29pbmcgdG8gdHJ5IHRoaXMgb3V0IHdpdGggdGhlIGNvZmZlZSB0YXN0aW5nIGRhdGEgZnJvbSB0aGUgW2Rpc3RyaWJ1dGlvbnMgcmVjaXRhdGlvbl0oM18wNl9kaXN0cmlidXRpb25zLzA2X2Rpc3RyaWJ1dGlvbnNfcmVjaXRhdGlvbl9zb2x1dGlvbnMuaHRtbCkKCkluc3RhbGwgYGdncmFkYXJgIGlmIHlvdSBkb24ndCBhbHJlYWR5IGhhdmUgaXQuIFRoaXMgcGFja2FnZSBpcyBub3QgYXZhaWxhYmxlIG9uIENSQU4gZm9yIHRoZSBuZXdlc3QgdmVyc2lvbiBvZiBSLCBzbyB3ZSBjYW4gdXNlIGBkZXZ0b29sc2AgYW5kIGBpbnN0YWxsX2dpdGh1YigpYCB0byBpbnN0YWxsIGl0LiBZb3UgY291bGQgYWxzbyB0cnkgdXNpbmcgYGluc3RhbGwucGFja2FnZXMoKWAgYW5kIHNlZSBpZiB0aGF0IHdvcmtzIGZvciB5b3UuCmBgYHtyIGdncmFkYXIgaW5zdGFsbCwgZXZhbCA9IEZBTFNFfQpkZXZ0b29sczo6aW5zdGFsbF9naXRodWIoInJpY2FyZG8tYmlvbi9nZ3JhZGFyIiwKICAgICAgICAgICAgICAgICAgICAgICAgIGRlcGVuZGVuY2llcyA9IFRSVUUpCmBgYAoKYGBge3IgZ2dyYWRhciBsaWJyYXJpZXMgZGF0YSwgd2FybmluZyA9IEZBTFNFLCBtZXNzYWdlID0gRkFMU0V9CmxpYnJhcnkoZ2dyYWRhcikKbGlicmFyeShzY2FsZXMpICMgZm9yIHNjYWxpbmcgZGF0YQoKIyBsb2FkIGNvZmZlZSBkYXRhIGZyb20gZGlzdHJpYnV0aW9ucyByZWNpdGF0aW9uCnR1ZXNkYXRhIDwtIHRpZHl0dWVzZGF5Ujo6dHRfbG9hZCgnMjAyMC0wNy0wNycpCgojIGV4dHJhY3Qgb3V0IGRmIG9uIGNvZmZlZV9yYXRpbmdzCmNvZmZlZSA8LSB0dWVzZGF0YSRjb2ZmZWVfcmF0aW5ncwoKIyB3aGF0IGFyZSB0aGUgY29sdW1uIG5hbWVzIGFnYWluPwpjb2xuYW1lcyhjb2ZmZWUpCmBgYAoKYGBge3IgZ2dyYWRhciB3cmFuZ2xpbmd9CmNvZmZlZV9yYWRhciA8LSBjb2ZmZWUgJT4lCiAgc2VsZWN0KHNwZWNpZXMsIGFyb21hOmN1cHBlcl9wb2ludHMpICU+JSAjIGZpcnN0IGNvbHVtbiBpcyB0aGUgZ3JvdXBzCiAgbXV0YXRlX2F0KHZhcnMoLXNwZWNpZXMpLCByZXNjYWxlKSAlPiUgIyBjb2x1bW5zIG5lZWQgdG8gYmUgYmV0d2VlbiAwIGFuZCAxCiAgZ3JvdXBfYnkoc3BlY2llcykgJT4lCiAgc3VtbWFyaXplX2lmKGlzLm51bWVyaWMsIG1lYW4pIAoKY29mZmVlX2xhYmVscyA8LSBjKCJBcm9tYSIsCiAgICAgICAgICAgICAgICAgICAiRmxhdm9yIiwKICAgICAgICAgICAgICAgICAgICJBZnRlcnRhc3RlIiwKICAgICAgICAgICAgICAgICAgICJBY2lkaXR5IiwKICAgICAgICAgICAgICAgICAgICJCb2R5IiwKICAgICAgICAgICAgICAgICAgICJCYWxhbmNlIiwKICAgICAgICAgICAgICAgICAgICJVbmlmb3JtaXR5IiwKICAgICAgICAgICAgICAgICAgICJDbGVhbiBjdXAiLAogICAgICAgICAgICAgICAgICAgIlN3ZWV0bmVzcyIsCiAgICAgICAgICAgICAgICAgICAiQ3VwcGVyIHBvaW50cyIpCmBgYAoKYGBge3IgZ2dyYWRhciBjb2ZmZWUgcmFkYXIgcGxvdH0KZ2dyYWRhcihjb2ZmZWVfcmFkYXIpCmBgYAoKYGBge3IgZ2dyYWRhciBjb2ZmZWUgcmFkYXIgcGxvdGNsZWFufQpnZ3JhZGFyKGNvZmZlZV9yYWRhciwKICAgICAgICBheGlzLmxhYmVscyA9IGNvZmZlZV9sYWJlbHMsCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIsCiAgICAgICAgYXhpcy5sYWJlbC5zaXplID0gMywKICAgICAgICBncmlkLmxhYmVsLnNpemUgPSA1KSArCiAgdGhlbWUobGVnZW5kLmtleSA9IGVsZW1lbnRfcmVjdChmaWxsID0gTkEsIGNvbG9yID0gTkEpLAogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE2KSwKICAgICAgICBsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpKSArCiAgbGFicyh0aXRsZSA9ICJEaWZmZXJlbmNlIGluIGF2ZXJhZ2UgY29mZmVlIGN1cHBlciBzY29yZSBcbmluIEFyYWJpY2EgYW5kIFJvYnVzdGEgYmVhbnMiKQpgYGAKCiMjIEhlYXRtYXBzIPCfn6XirJzvuI/wn5+mCgojIyMgSW5zdGFsbApgYGB7ciBwaGVhdG1hcCBpbnN0YWxsLCBldmFsID0gRkFMU0V9Cmluc3RhbGwucGFja2FnZXMoInBoZWF0bWFwIikKYGBgCgojIyMgTG9hZCBsaWJyYXJpZXMKYGBge3IgcGhlYXRtYXAgbGlicmFyeX0KbGlicmFyeShwaGVhdG1hcCkKYGBgCgojIyMgUGxvdApgYGB7ciBwaGVhdG1hcCBwbG90fQpwaGVhdG1hcChtdGNhcnMpCmBgYAoKYGBge3IgcGhlYXRtYXAgcGxvdCBzY2FsZWQgY2x1c3RlcmVkfQpwaGVhdG1hcChtdGNhcnMsIAogICAgICAgICBzY2FsZSA9ICJjb2x1bW4iLAogICAgICAgICBjbHVzdGVyX3Jvd3MgPSBUUlVFKSAjIGNsdXN0ZXIgcm93cyBiYXNlZCBvbiBzaW1pbGFyaXR5CmBgYAoKCiMjIyBDb25wbGV4SGVhdG1hcAoKVGhlIHBhY2thZ2UgW2BDb21wbGV4SGVhdG1hcGBdKGh0dHBzOi8vam9rZXJnb28uZ2l0aHViLmlvL0NvbXBsZXhIZWF0bWFwLXJlZmVyZW5jZS9ib29rL2luZGV4Lmh0bWwpIGFsbG93cyBtb3JlIGN1c3RvbWl6ZWQgYW5kIGNvbXBsaWNhdGVkIGhlYXRtYXBzIHRvIGJlIHByb2R1Y2VkLiBJZiB5b3UgYXJlIGludGVyZXN0ZWQgaW4gbWFraW5nIGhlYXRtYXBzLCB0aGlzIHBhY2thZ2UgaXMgd29ydGggdG8gY2hlY2sgb3V0LgoKIyMgSW4gY2xhc3MKCkluIGNsYXNzLCB3ZSB3aWxsIHByYWN0aWNlIG1ha2luZyB1c2Ugb2YgdGhlc2UgbGVmdG92ZXJzLgoKIyMjIFVzZWZ1bCByZXNvdXJjZXMKCi0gW2BnZ2hpZ2hsaWdodGBdKGh0dHBzOi8veXV0YW5uaWhpbGF0aW9uLmdpdGh1Yi5pby9nZ2hpZ2hsaWdodC8pCi0gW2BwYXRjaHdvcmtgXShodHRwczovL3BhdGNod29yay5kYXRhLWltYWdpbmlzdC5jb20vKQotIFtgZ2dhbmltYXRlYF0oaHR0cHM6Ly9nZ2FuaW1hdGUuY29tLykKLSBbYGdncmFkYXJgXShodHRwczovL3d3dy5yZG9jdW1lbnRhdGlvbi5vcmcvcGFja2FnZXMvZ2dyYWRhci92ZXJzaW9ucy8wLjIpCi0gW2BwaGVhdG1hcGBdKGh0dHBzOi8vd3d3LnJkb2N1bWVudGF0aW9uLm9yZy9wYWNrYWdlcy9waGVhdG1hcC92ZXJzaW9ucy8xLjAuMTIvdG9waWNzL3BoZWF0bWFwKQotIFtwaGVhdG1hcCgpXShodHRwczovL3d3dy5yZG9jdW1lbnRhdGlvbi5vcmcvcGFja2FnZXMvcGhlYXRtYXAvdmVyc2lvbnMvMS4wLjEyL3RvcGljcy9waGVhdG1hcCkKLSBbQ29tcGxleEhlYXRtYXBdKCk=